package com.mtw.bbs.fileAdmin.util;

import lombok.extern.slf4j.Slf4j;
import org.bytedeco.ffmpeg.avformat.AVFormatContext;
import org.bytedeco.ffmpeg.avformat.AVStream;
import org.bytedeco.ffmpeg.avutil.AVRational;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Java2DFrameConverter;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import static org.bytedeco.ffmpeg.global.avutil.AVMEDIA_TYPE_VIDEO;

/**
 * 视频工具类
 */
@Slf4j
public class VideoUtil {


    /**
     * 获取视频封面
     */
    public static void captureFirstFrameJPG(File video, File cover) {

        try {
            FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(video);
            grabber.start();
            // 读取第一帧
            Java2DFrameConverter converter = new Java2DFrameConverter();
            BufferedImage firstFrame = converter.convert(grabber.grabImage());
            // 将图像保存到指定路径
            ImageIO.write(firstFrame, "jpg", cover);
            grabber.stop();
        } catch (IOException e) {
            log.error("无法截取第一帧图像：{}",e.getMessage());
            throw new RuntimeException("无法截取第一帧图像");
        }
    }


    /**
     * 获取视频封面和时长
     */
    public static Long getVideoCoverAndDuration(InputStream video, File cover) {

        try(FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(video);Java2DFrameConverter converter = new Java2DFrameConverter()) {

            grabber.start();
            // 获取 AVFormatContext，它包含了视频文件的元数据
            AVFormatContext formatContext = grabber.getFormatContext();
            AVStream stream = formatContext.streams(0);

            // 不是是视频流
            if (stream.codecpar().codec_type() != AVMEDIA_TYPE_VIDEO) {
                grabber.stop();
               return 0L;
            }

            // 读取第一帧
            BufferedImage firstFrame = converter.convert(grabber.grabImage());
            // 将图像保存到指定路径
            ImageIO.write(firstFrame, "jpg", cover);

            // 获取时间基准
            AVRational timeBase = stream.time_base();
            // 获取视频时长（以时间基准为单位）
            long durationInTicks = stream.duration();
            // 将时长从时间基准单位转换为秒
            long durationInSeconds = durationInTicks * timeBase.num() / timeBase.den();
            grabber.stop();
            return durationInSeconds;
        } catch (Exception e) {
            log.error("无法截取第一帧图像：{}",e.getMessage());
            throw new RuntimeException("无法截取第一帧图像");
        }
    }
}
